package com.tgy.blog.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.tgy.ao.LoginAo;
import com.tgy.ao.UserRegisterAo;
import com.tgy.blog.service.DeskUserService;
import com.tgy.constant.Constant;
import com.tgy.core.service.BlogUserService;
import com.tgy.enums.ArticleReviewLevel;
import com.tgy.enums.ResponseStatusEnum;
import com.tgy.enums.Sex;
import com.tgy.jwt.JWTUtils;
import com.tgy.pojo.BlogUser;
import com.tgy.result.GraceJSONResult;
import com.tgy.util.AddressUtils;
import com.tgy.util.aliyun.AliTextReviewUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * @author tianguiyin
 * @version 1.0
 * @date 2022/7/19 10:35
 */
@Service
public class DeskUserServiceImp implements DeskUserService {

    @Resource
    private BlogUserService blogUserService;
    @Resource
    private AliTextReviewUtils aliTextReviewUtils;

    @Value("${sa-token.timeout}")
    private Integer timeout;

    @Value("${tgy.manAvatarImage}")
    private String manImage;
    @Value("${tgy.womanAvatarImage}")
    private String womanImage;

    @Override
    public GraceJSONResult login(LoginAo ao) {
        // 判断账号是否存在
        BlogUser user = new BlogUser();
        user.setAccount(ao.getUsername());
        List<BlogUser> userList = blogUserService.queryList(user);
        if (CollectionUtil.isEmpty(userList)){
            return GraceJSONResult.error(ResponseStatusEnum.LOGIN_USER_NOTFOND.msg());
        }
        BlogUser loginUser = userList.get(0);
        // 判断账号状态
        if (Constant.AVAILABLE_FALSE.equals(loginUser.getStatus())){
            return GraceJSONResult.error(ResponseStatusEnum.LOGIN_USER_ERRORSTATUS.msg());
        }
        if (!BCrypt.checkpw(ao.getPassword(), loginUser.getPassword())){
            return GraceJSONResult.error(ResponseStatusEnum.LOGIN_PASSWORD_ERROR.msg());
        }
        //登录成功
        String token = JWTUtils.getTokenOfJSON(loginUser.getId(), JSONObject.toJSONString(loginUser), timeout);
        Map<String,Object> map = new HashMap<>();
        map.put("userId",loginUser.getId());
        map.put("token",token);
        map.put("time",timeout);

        // 记录最后一次登录地址信息
        loginUser.setLatelyLoginTime(LocalDateTime.now());
        String ip = ao.getIp();
        loginUser.setLatelyLoginIp(ip);
        String address = getAddressByIp(ip);
        loginUser.setLatelyLoginAddress(address);
        blogUserService.updateByBo(loginUser);

        return GraceJSONResult.ok(map);
    }

    @Override
    public GraceJSONResult register(UserRegisterAo ao) {
        BlogUser blogUser = new BlogUser();

        // 判断账号、昵称是否存在
        BlogUser user = new BlogUser();
        user.setAccount(ao.getAccount());
        List<BlogUser> userList = blogUserService.queryByAccountAndNick(ao.getAccount(),ao.getNickname());
        if (CollectionUtil.isNotEmpty(userList)){
            return GraceJSONResult.error(ResponseStatusEnum.ACCOUNT_OR_NICKNAME_THERE.msg());
        }

        // 验证账号密码设置是否合理
        // String regExp = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[._~!@#$^&*])[A-Za-z0-9._~!@#$^&*]{8,20}$";
        // String regExp = "^(?=.*[a-zA-Z])(?=.*[0-9])[A-Za-z0-9]{8,18}$";
        // 必须是6-12位的字母、数字、下划线
        String regExp = "^[\\w_]{6,12}$";
        if(!Pattern.matches(regExp, ao.getAccount())) {
            return GraceJSONResult.error(ResponseStatusEnum.ACCOUNT_OR_PASSWORD_ERROR.msg());
        }
        if(!Pattern.matches(regExp, ao.getPassword())) {
            return GraceJSONResult.error(ResponseStatusEnum.ACCOUNT_OR_PASSWORD_ERROR.msg());
        }
        if (ao.getNickname().contains(" ")){
            return GraceJSONResult.error("昵称不能有空格");
        }
        if (ao.getNickname().length()>12){
            return GraceJSONResult.error("昵称长度不能大于12个字符");
        }

        String s = aliTextReviewUtils.reviewTextContent(ao.getNickname());
        if (!ArticleReviewLevel.PASS.type.equals(s)){
            return GraceJSONResult.error("请文明取昵称");
        }

        // 添加账号
        String password = BCrypt.hashpw(ao.getPassword());
        BeanUtil.copyProperties(ao,blogUser);
        blogUser.setPassword(password);
        blogUser.setStatus(Constant.AVAILABLE_TRUE);
        if (Sex.man.value.equals(ao.getSex())){
            blogUser.setHeadPortrait(manImage);
        }else {
            blogUser.setHeadPortrait(womanImage);
        }

        LocalDateTime nowDate = LocalDateTime.now();
        blogUser.setRegistrationDate(nowDate);
        blogUser.setLatelyLoginTime(nowDate);
        String ip = ao.getIp();
        blogUser.setLatelyLoginIp(ip);
        String address = getAddressByIp(ip);
        blogUser.setLatelyLoginAddress(address);
        blogUser.setAddress(address);

        blogUser.setCreatedTime(nowDate);
        blogUser.setUpdatedTime(nowDate);

        Boolean aBoolean = blogUserService.insertByBo(blogUser);
        if (aBoolean){
            return GraceJSONResult.ok("注册成功");
        }else {
            return GraceJSONResult.ok("注册失败");
        }
    }

    /**
     * 根据IP地址获取实际地理信息
     */
    private String getAddressByIp(String ip) {
        String address = "";
        if (StrUtil.isNotBlank(ip)){
            try {
                address = AddressUtils.getAddress(ip);
            } catch (IOException e) {
                System.out.println("获取地址失败");
                e.printStackTrace();
            }
        }
        return address;
    }

    @Override
    public GraceJSONResult logout() {
        return null;
    }
}
